﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace TicTacToe
{
    public class GameBoard
    {
        public enum SquareStatus
        {
            Empty,
            EmptySelected,
            Circle,
            CircleSelected,
            Cross,
            CrossSelected
        } ;

        public static int[][] StaticEvaluation = { new int[] { 3, 2, 3 },
                                           new int[] { 2, 4, 2 },
                                           new int[] { 3, 2, 3 } };

        public static int _gameboardWidth = 3;
        public static int _gameboardHeight = 3;
        public SquareStatus[,] _squares;
        private int _squareWidth = 80;
        private int _squareHeight = 80;
        private int _squarePadding = 5;
        private Vector2 _currentlySelected;
        private Texture2D _spriteSheet;

        public GameBoard(Texture2D spriteSheet)
        {
            _spriteSheet = spriteSheet;
            _squares = new SquareStatus[_gameboardWidth, _gameboardHeight];
            _currentlySelected = new Vector2(0, 0);
            InitGameBoard();
        }

        public void InitGameBoard()
        {

            for(int i = 0; i < _gameboardWidth; i++)
                for(int j = 0; j < _gameboardHeight; j++)
                {
                    _squares[i, j] = SquareStatus.Empty;
                }

            _squares[0, 0] = SquareStatus.EmptySelected;
            _currentlySelected = new Vector2(0, 0);
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            for(int i = 0; i < 3; i++)
                for(int j = 0; j < 3; j++)
                {
                    spriteBatch.Draw(_spriteSheet,
                        new Rectangle((i * _squareWidth) + (i * _squarePadding), (j * _squareHeight) + (j * _squarePadding), _squareWidth, _squareHeight), 
                        GetSourceRectangle(_squares[i, j]), 
                        Color.White );
                }           
        }

        private Rectangle GetSourceRectangle(SquareStatus squareStatus)
        {
            switch(squareStatus)
            {
                case SquareStatus.Empty:
                    return new Rectangle(160, 80, 80, 80);
                    
                case SquareStatus.EmptySelected:
                    return new Rectangle(160, 0, 80, 80);
                    
                case SquareStatus.Circle:
                    return new Rectangle(0, 0, 80, 80);
                    
                case SquareStatus.CircleSelected:
                    return new Rectangle(80, 0, 80, 80);
                    
                case SquareStatus.Cross:
                    return new Rectangle(0, 80, 80, 80);
                    
                case SquareStatus.CrossSelected:
                    return new Rectangle(80, 80, 80, 80);
                    
                default:
                    return new Rectangle(0,0,80,80);
            }
        }

        public void MoveLeft()
        {
            if(_currentlySelected.X > 0)
            {
                Deselect(_currentlySelected);
                _currentlySelected.X -= 1;
                Select(_currentlySelected);
            }  
        }

        private void Select(Vector2 currentlySelected)
        {
            var square = _squares[(int) currentlySelected.X, (int) currentlySelected.Y];
            switch (square)
            {
                case SquareStatus.Circle:
                    _squares[(int)currentlySelected.X, (int)currentlySelected.Y] = SquareStatus.CircleSelected;
                    break;
                case SquareStatus.Cross:
                    _squares[(int)currentlySelected.X, (int)currentlySelected.Y] = SquareStatus.CrossSelected;
                    break;
                case SquareStatus.Empty:
                    _squares[(int)currentlySelected.X, (int)currentlySelected.Y] = SquareStatus.EmptySelected;
                    break;
            }
        }

        private void Deselect(Vector2 currentlySelected)
        {
            var square = _squares[(int)currentlySelected.X, (int)currentlySelected.Y];
            switch (square)
            {
                case SquareStatus.CircleSelected:
                    _squares[(int)currentlySelected.X, (int)currentlySelected.Y] = SquareStatus.Circle;
                    break;
                case SquareStatus.CrossSelected:
                    _squares[(int)currentlySelected.X, (int)currentlySelected.Y] = SquareStatus.Cross;
                    break;
                case SquareStatus.EmptySelected:
                    _squares[(int)currentlySelected.X, (int)currentlySelected.Y] = SquareStatus.Empty;
                    break;
            }
        }

        public void MoveRight()
        {
            if (_currentlySelected.X < 2)
            {
                Deselect(_currentlySelected);
                _currentlySelected.X += 1;
                Select(_currentlySelected);
            } 
            
        }

        public void MoveUp()
        {
            if (_currentlySelected.Y > 0)
            {
                Deselect(_currentlySelected);
                _currentlySelected.Y -= 1;
                Select(_currentlySelected);
            } 
            
        }

        public void MoveDown()
        {
            if (_currentlySelected.Y < 2)
            {
                Deselect(_currentlySelected);
                _currentlySelected.Y += 1;
                Select(_currentlySelected);
            }
        }
        
        public bool InsertPlayerPiece()
        {
           
            if(_squares[(int)_currentlySelected.X, (int)_currentlySelected.Y] == SquareStatus.EmptySelected)
            {
                _squares[(int) _currentlySelected.X, (int) _currentlySelected.Y] = SquareStatus.CrossSelected;
                return true;
            }

            return false;
        }

        public static bool CheckIfCircleWon(SquareStatus[,] state)
        {
            for(int i = 0; i < _gameboardWidth; i++)
            {
                if ((state[i, 0] == SquareStatus.Circle || state[i, 0] == SquareStatus.CircleSelected) &&
                    (state[i, 1] == SquareStatus.Circle || state[i, 1] == SquareStatus.CircleSelected) &&
                    (state[i, 2] == SquareStatus.Circle || state[i, 2] == SquareStatus.CircleSelected))
                    return true;
            }
            for(int j = 0; j < _gameboardHeight; j++)
            {
                if ((state[0, j] == SquareStatus.Circle || state[0, j] == SquareStatus.CircleSelected) &&
                     (state[1, j] == SquareStatus.Circle || state[1, j] == SquareStatus.CircleSelected) &&
                     (state[2, j] == SquareStatus.Circle || state[2, j] == SquareStatus.CircleSelected))
                    return true; 
            }

            if ((state[0, 0] == SquareStatus.Circle || state[0, 0] == SquareStatus.CircleSelected) &&
                    (state[1, 1] == SquareStatus.Circle || state[1, 1] == SquareStatus.CircleSelected) &&
                    (state[2, 2] == SquareStatus.Circle || state[2, 2] == SquareStatus.CircleSelected))
                return true;

            if ((state[0, 2] == SquareStatus.Circle || state[0, 2] == SquareStatus.CircleSelected) &&
                (state[1, 1] == SquareStatus.Circle || state[1, 1] == SquareStatus.CircleSelected) &&
                (state[2, 0] == SquareStatus.Circle || state[2, 0] == SquareStatus.CircleSelected))
                return true;

            return false;
        }

        public static bool CheckIfCrossWon(SquareStatus[,] state)
        {
            for (int i = 0; i < _gameboardWidth; i++)
            {
                if ((state[i, 0] == SquareStatus.Cross || state[i, 0] == SquareStatus.CrossSelected) &&
                    (state[i, 1] == SquareStatus.Cross || state[i, 1] == SquareStatus.CrossSelected) &&
                    (state[i, 2] == SquareStatus.Cross || state[i, 2] == SquareStatus.CrossSelected))
                    return true;
            }
            for (int j = 0; j < _gameboardHeight; j++)
            {
                if ((state[0, j] == SquareStatus.Cross || state[0, j] == SquareStatus.CrossSelected) &&
                     (state[1, j] == SquareStatus.Cross || state[1, j] == SquareStatus.CrossSelected) &&
                     (state[2, j] == SquareStatus.Cross || state[2, j] == SquareStatus.CrossSelected))
                    return true;
            }

            if ((state[0, 0] == SquareStatus.Cross || state[0, 0] == SquareStatus.CrossSelected) &&
                    (state[1, 1] == SquareStatus.Cross || state[1, 1] == SquareStatus.CrossSelected) &&
                    (state[2, 2] == SquareStatus.Cross || state[2, 2] == SquareStatus.CrossSelected))
                return true;

            if ((state[0, 2] == SquareStatus.Cross || state[0, 2] == SquareStatus.CrossSelected) &&
                (state[1, 1] == SquareStatus.Cross || state[1, 1] == SquareStatus.CrossSelected) &&
                (state[2, 0] == SquareStatus.Cross || state[2, 0] == SquareStatus.CrossSelected))
                return true;

            return false;
        }

        public static bool CheckForDraw(GameBoard.SquareStatus[,] _squares)
        {
            bool Empties = true;
            if (!GameBoard.CheckIfCircleWon(_squares) && !GameBoard.CheckIfCrossWon(_squares))
            {
                foreach (var node in _squares)
                    if (node == GameBoard.SquareStatus.Empty || node == GameBoard.SquareStatus.EmptySelected)
                        Empties = false;
            }
            return Empties;
        }

        public static SquareStatus[,] CalculateNextComputerMove(SquareStatus[,] _squares)
        {
            return new MinMax(_squares, 5, MinMaxType.Minimizer).NextMove();            
        }
    }
}
